import z from "zod";

/** 消息模板 */
export const enum ENUM_MessageCodeTemplate {
  required = "缺少%n:40000",
  format = "%n格式错误:40001",
  empaty = "%n不能为空:40002",
  invalid = "%n数据无效:40003",
  exist = "%n已存在:40004",
  notExist = "%n不存在:40005",
  notMatch = "%n不匹配:40006",
  notIn = "%n不在范围内:40007",
  notInclude = "%n不包含:40008",
  min = "%n不能小于%v1:40009",
  max = "%n不能大于%v1:40010",
  length = "%n长度必须为%v1:40011",
  lengthMin = "%n长度不能小于%v1:40012",
  lengthMax = "%n长度不能大于%v1:40013",
  lengthRange = "%n长度必须在%v1和%v2之间:40014",
}

export const buildMessageCode = (
  messageCodeTemplate: ENUM_MessageCodeTemplate,
  name: string,
  value?: string,
  value2?: string
): string => {
  let str = messageCodeTemplate.replace("%n", name);
  if (value2) str = str.replace("%v2", value2);
  return value ? str.replace("%v1", value) : str;
};

/** 字符串 - 填写、字符串、不能为空 */
export const valid_base_string = (name: string) => {
  return z
    .string({
      required_error: buildMessageCode(ENUM_MessageCodeTemplate.required, name),
      invalid_type_error: buildMessageCode(
        ENUM_MessageCodeTemplate.invalid,
        name
      ),
    })
    .min(1, {
      message: buildMessageCode(ENUM_MessageCodeTemplate.empaty, name),
    });
};

/** 数值 - 填写、数值*/
export const valid_base_number = (name: string) => {
  return z.number({
    required_error: buildMessageCode(ENUM_MessageCodeTemplate.required, name),
    invalid_type_error: buildMessageCode(
      ENUM_MessageCodeTemplate.invalid,
      name
    ),
  });
};

/** 真假 - 填写、boolean */
export const valid_base_boolean = (name: string) => {
  return z.boolean({
    required_error: buildMessageCode(ENUM_MessageCodeTemplate.required, name),
    invalid_type_error: buildMessageCode(
      ENUM_MessageCodeTemplate.invalid,
      name
    ),
  });
};

/** 日期时间 - 填写、Date、默认值为当前时间 */
export const valid_base_dateTime = (name: string) => {
  return z
    .date({
      required_error: buildMessageCode(ENUM_MessageCodeTemplate.required, name),
      invalid_type_error: buildMessageCode(
        ENUM_MessageCodeTemplate.invalid,
        name
      ),
    })
    .default(new Date());
};

/** 枚举类型参数 - 填写、枚举 */
export const valid_base_enum = (e: z.EnumLike, name: string) => {
  return z.nativeEnum(e, {
    required_error: buildMessageCode(ENUM_MessageCodeTemplate.required, name),
    invalid_type_error: buildMessageCode(
      ENUM_MessageCodeTemplate.invalid,
      name
    ),
  });
};

/** 数组 - 填写、数组、默认空数组 */
export const valid_base_array = (arr: z.ZodTypeAny, name: string) => {
  return z.array(arr, {
    required_error: buildMessageCode(ENUM_MessageCodeTemplate.required, name),
    invalid_type_error: buildMessageCode(
      ENUM_MessageCodeTemplate.invalid,
      name
    ),
  });
};

/** ID */
export const valid_id = (name: string = "id") => {
  return valid_base_string(name).length(24, {
    message: buildMessageCode(ENUM_MessageCodeTemplate.format, name),
  });
};

/** name */
export const valid_name = (name: string = "名称") => {
  return valid_base_string(name).min(1, {
    message: buildMessageCode(ENUM_MessageCodeTemplate.empaty, name),
  });
};

/** 手机号 */
export const valid_phone = (name: string = "手机号") => {
  return valid_base_string(name).regex(/^1[1-9]\d{9}$/, {
    message: buildMessageCode(ENUM_MessageCodeTemplate.format, name),
  });
};

/** 密码 */
export const valid_password = (name: string = "密码") => {
  return valid_base_string(name)
    .min(1, {
      message: buildMessageCode(ENUM_MessageCodeTemplate.empaty, name),
    })
    .refine(
      (value) => {
        return value.length >= 6 && value.length <= 16;
      },
      {
        message: buildMessageCode(
          ENUM_MessageCodeTemplate.lengthRange,
          name,
          "6",
          "16"
        ),
        path: ["password"],
      }
    );
};

export const valid_price = (name: string = "价格") => {
  return valid_base_number(name)
    .min(0, {
      message: buildMessageCode(ENUM_MessageCodeTemplate.min, name, "0"),
    })
    .default(0);
};

/** 0~100百分比 */
export const valid_ratio = (name: string = "百分比") => {
  return valid_base_number(name)
    .min(0, {
      message: buildMessageCode(ENUM_MessageCodeTemplate.min, name, "0"),
    })
    .max(100, {
      message: buildMessageCode(ENUM_MessageCodeTemplate.max, name, "100"),
    })
    .default(0);
};

/** 备注 */
export const valid_desc = (name: string = "备注") => {
  return valid_base_string(name).default("");
};
